package com.example.cks_show_text.usb;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.util.Log;


import com.example.cks_show_text.MainActivity;
import com.example.cks_show_text.MyApplication;
import com.example.cks_show_text.util.ByteUtil;
import com.hoho.android.usbserial.driver.UsbSerialDriver;
import com.hoho.android.usbserial.driver.UsbSerialPort;
import com.hoho.android.usbserial.driver.UsbSerialProber;
import com.hoho.android.usbserial.util.SerialInputOutputManager;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;

/**
 * 人脸识别模块：usb转串口通信
 * 1.识别到目标后，获取温度数据并显示
 */
public class FaceHandlerUSB implements SerialInputOutputManager.Listener {
    String TAG = FaceHandlerUSB.class.getSimpleName();
    UsbManager usbManager;
    UsbSerialPort usbSerialPort;
    SerialInputOutputManager usbIoManager;
    private static final String ACTION_DEVICE_PERMISSION = "com.linc.USB_PERMISSION";
    private boolean connected = false;
    static FaceHandlerUSB faceHandlerUSB;
    USBBack usbBack = null;
    private FaceHandlerUSB(){}
    public static synchronized FaceHandlerUSB getInstance(){
        if(faceHandlerUSB == null){
            faceHandlerUSB = new FaceHandlerUSB();
            faceHandlerUSB.usbInit();
        }
        return faceHandlerUSB;
    }
    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_DEVICE_PERMISSION.equals(action)) {
                synchronized (this) {
                    UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        if (device != null) {
                            Log.d(TAG, "usbInit: usb work!");
                            connect(device);
                        }
                    }
                }
            }
        }
    };
    private void usbInit() {
        usbManager = (UsbManager) MyApplication.getMContenx().getSystemService(Context.USB_SERVICE);
        HashMap<String, UsbDevice> deviceHashMap = usbManager.getDeviceList();
        Iterator<UsbDevice> iterator = deviceHashMap.values().iterator();
        while (iterator.hasNext()) {
            UsbDevice device = iterator.next();
            ///dev/bus/usb/001/006
            Log.d(TAG, "usbInit: " + device.getDeviceName());
            //USB2.0-Serial
            Log.d(TAG, "usbInit: " + device.getProductName());
            //6790
            Log.d(TAG, "usbInit: " + device.getVendorId());
            //29987
            Log.d(TAG, "usbInit: " + device.getProductId());
            if (device.getProductId() == 9155 && device.getVendorId() == 1659) {
            // 人脸识别usb
                if (usbManager.hasPermission(device)) {
                    Log.d(TAG, "usbInit: usb work!");
                    connect(device);
                } else {
                    PendingIntent mPermissionIntent = PendingIntent.getBroadcast(MyApplication.getMContenx(), 0, new Intent(ACTION_DEVICE_PERMISSION), 0);
                    IntentFilter permissionFilter = new IntentFilter(ACTION_DEVICE_PERMISSION);
                    MyApplication.getMContenx().registerReceiver(mUsbReceiver, permissionFilter);
                    usbManager.requestPermission(device, mPermissionIntent);
                }
            }
        }
    }
    private void connect(UsbDevice mUsbDevice) {
        if (mUsbDevice != null) {
            UsbSerialDriver driver = UsbSerialProber.getDefaultProber().probeDevice(mUsbDevice);
            if (driver == null){
                driver = CustomProber.getCustomProber().probeDevice(mUsbDevice);
            }
            if (driver == null) {
                Log.d(TAG, "connect: no driver for device");
                return;
            }
            for (int i = 0; i < driver.getPorts().size(); i++) {
                Log.d(TAG, "connect: " + driver.getPorts().get(i));
            }
            usbSerialPort = driver.getPorts().get(0);
            UsbDeviceConnection usbDeviceConnection = usbManager.openDevice(driver.getDevice());//连接usb设备
            if (usbDeviceConnection == null) {
                return;
            }
            try {
                usbSerialPort.open(usbDeviceConnection);
                usbSerialPort.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);
                usbIoManager = new SerialInputOutputManager(usbSerialPort, this);
                usbIoManager.start();
                connected = true;
            } catch (Exception e) {
                disconnect();
            }
        }
    }

    /**
     * 向usb串口发送Byte[]
     * @param data
     */
    public void send(byte[] data){
        if(!connected){
            Log.d(TAG, "send: not connected!");
            usbInit();
            return;
        }
        try {
            usbSerialPort.write(data, 100);
        } catch (IOException e) {
            Log.d(TAG, "send Error: " + e.toString());
            e.printStackTrace();
        }
    }
    /**
     * 向usb串口发送字符串
     * @param str
     */
    public void send(String str) {
        send(ByteUtil.hexString2ByteArray(str));
    }
    private void disconnect() {
        connected = false;
        if (usbIoManager != null) {
            usbIoManager.setListener(null);
            usbIoManager.stop();
        }
        usbIoManager = null;
        try {
            usbSerialPort.close();
        } catch (IOException ignored) {
        }
        usbSerialPort = null;
    }
    @Override
    public void onNewData(byte[] data) {
//        Log.d(TAG, "onNewData: " + ByteUtil.byteArray2HexString(data));
        if(faceHandlerUSB.usbBack!=null){
            faceHandlerUSB.usbBack.bakc(data);
        }
    }

    @Override
    public void onRunError(Exception e) {
        Log.d(TAG, "onRunError: " + e.toString());
    }

    public void stopusb() {
        disconnect();
        this.usbBack = null;
    }

    public void setBackLinsten(USBBack mainActivity) {
        faceHandlerUSB.usbBack = mainActivity;
    }
}
